package case19

import (
	"bufio"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
	"time"
)

func Test() {
	fmt.Println("🎯示例十九：分页单表查询")

	db, err := mysqlConnect()
	if err != nil {
		fmt.Println(err)
		return
	}

	// 创建表结构
	db.AutoMigrate(&UserCase19{})

	//// 批量插入数据
	//uArr1 := []UserCase19{
	//	{Name: "LILI"},
	//	{Name: "小红"},
	//	{Name: "小明"},
	//	{Name: "小名"},
	//	{Name: "小蓝"},
	//	{Name: "小卡"},
	//	{Name: "小罗"},
	//	{Name: "小啦"},
	//	{Name: "哆啦A梦"},
	//	{Name: "樱桃小丸子"},
	//	{Name: "忍者神龟"},
	//	{Name: "柯南神探"},
	//	{Name: "z*朝着"},
	//	{Name: "足球小将"},
	//	{Name: "聪明的阿修"},
	//}
	//db.Create(&uArr1)

	// 控制台输入监听
	reader := bufio.NewReader(os.Stdin)
	for {
		fmt.Print("> ")
		data, err := reader.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				fmt.Println("输入结束")
				break
			}
			fmt.Println("读取错误：", err)
			break
		}

		fmt.Print("请输入页数：")
		pageNum, _ := reader.ReadString('\n')
		pageNum = strings.TrimSpace(pageNum)
		fmt.Print("请输入条数：")
		sizeNum, _ := reader.ReadString('\n')
		sizeNum = strings.TrimSpace(sizeNum)

		// 去除换行符
		data = strings.TrimSpace(data)
		if data == "q" {
			fmt.Println("推出程序")
			break
		}
		if data != "" {
			fmt.Println("你输入了：", data)
			fmt.Println("页数 ： 条数：", pageNum, sizeNum)

			// 分页
			uArr1 := []UserCase19{}
			var total int64

			db.Model(&UserCase19{}).Count(&total)
			db.Scopes(Paginate(StrToInt(pageNum, 0), StrToInt(sizeNum, 0))).Find(&uArr1)
			//db.Scopes(Paginate(StrToInt("2", 0), StrToInt("5", 0))).Find(&uArr1)
			//db.Scopes(Paginate(2, 10)).Find(&uArr1)
			for _, u := range uArr1 {
				fmt.Println(u)
			}

		}
	}

	fmt.Println(db)
}

// 初始化连接
func mysqlConnect() (*gorm.DB, error) {
	url := "root:123456@tcp(127.0.0.1:3306)/case1?charset=utf8mb4&parseTime=True&loc=Local"

	// 配置自定义 Logger 打印sql日志
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			SlowThreshold:             time.Second, // 慢 SQL 阈值
			LogLevel:                  logger.Info, // 可以设置为不同级别 Silent-不打印任何日志 Error-只打印错误日志 Warn-打印慢查询和错误 Info-打印慢查询和错误
			IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound（记录未找到）错误
			Colorful:                  true,        // 彩色打印
		},
	)

	db, err := gorm.Open(mysql.Open(url), &gorm.Config{
		Logger: newLogger, // 设置 Logger
		NamingStrategy: schema.NamingStrategy{
			SingularTable: true, // 关闭默认，使用表名
		},
	})
	if err != nil {
		return nil, fmt.Errorf("mysql connect err: %v", err)
	}

	sqlDB, err := db.DB()
	if err != nil {
		panic("failed to get sql.DB")
	}

	// 配置连接池
	// 最大空闲连接数 - 应该小于最大打开连接数
	sqlDB.SetMaxIdleConns(20)
	// 最大打开连接数 - 根据应用负载和MySQL配置调整
	sqlDB.SetMaxOpenConns(100)
	// 连接最大生命周期 - 小于MySQL的wait_timeout设置
	sqlDB.SetConnMaxLifetime(5 * time.Minute)
	// 空闲连接最大存活时间
	sqlDB.SetConnMaxIdleTime(10 * time.Minute)

	return db, nil
}

// 数据表结构体
type UserCase19 struct {
	ID         int       `gorm:"primarykey;autoIncrement"`
	Name       string    `gorm:"type:varchar(50);"`
	CreateTime time.Time `gorm:"type:datetime;autoCreateTime"`            //自动设置创建时间
	UpdateTime time.Time `gorm:"type:datetime;default:CURRENT_TIMESTAMP"` //设置默认值
}

// 基本分页查询
func Paginate(page, pageSize int) func(db *gorm.DB) *gorm.DB {
	return func(db *gorm.DB) *gorm.DB {
		if page <= 0 {
			page = 1
		}
		switch {
		case pageSize > 100:
			pageSize = 100
		case pageSize <= 0:
			pageSize = 10
		}
		offset := (page - 1) * pageSize
		return db.Offset(offset).Limit(pageSize)
	}
}

//// 链式调用分页
//func (db *gorm.DB) Paginate(page, pageSize int) *gorm.DB {
//	if page <= 0 {
//		page = 1
//	}
//	if pageSize <= 0 {
//		pageSize = 10
//	}
//	offset := (page - 1) * pageSize
//	return db.Offset(offset).Limit(pageSize)
//}

// 字符串转int，转换失败返回默认值
func StrToInt(str string, defaultValue int) int {
	num, err := strconv.Atoi(str)
	if err != nil {
		return defaultValue
	}
	return num
}
